`timescale 1ns / 1ps

// Copyright 2023 Sycuricon Group
// Author: Jinyan Xu (phantom@zju.edu.cn)
`include "CSRStruct.vh"
`include "RegStruct.vh"
`include "MMUStruct.vh"

module top (
    input  wire        clk,
    input  wire        rstn,
    input  wire [15:0] switch,
    input  wire [ 4:0] btn,
    output wire [15:0] led,
    output wire [ 7:0] cs,
    output wire [ 7:0] an,
    output wire        vga_hs,
    output wire        vga_vs,
    output wire [ 3:0] vga_r,
    output wire [ 3:0] vga_g,
    output wire [ 3:0] vga_b,

    inout  [15:0] ddr2_dq,
    inout  [ 1:0] ddr2_dqs_n,
    inout  [ 1:0] ddr2_dqs_p,
    output [12:0] ddr2_addr,
    output [ 2:0] ddr2_ba,
    output        ddr2_ras_n,
    output        ddr2_cas_n,
    output        ddr2_we_n,
    output [ 0:0] ddr2_ck_p,
    output [ 0:0] ddr2_ck_n,
    output [ 0:0] ddr2_cke,
    output [ 0:0] ddr2_cs_n,
    output [ 1:0] ddr2_dm,
    output [ 0:0] ddr2_odt
);
    wire        clk_core;
    wire        cosim_mmio_store;
    wire [63:0] cosim_mmio_len;
    wire [63:0] cosim_mmio_val;
    wire [63:0] cosim_mmio_addr;
    wire        cosim_interrupt;
    wire [63:0] cosim_cause;
    wire        cosim_valid;
    wire [63:0] cosim_pc;
    wire [31:0] cosim_inst;
    wire [ 7:0] cosim_rs1_id;
    wire [63:0] cosim_rs1_data;
    wire [ 7:0] cosim_rs2_id;
    wire [63:0] cosim_rs2_data;
    wire [63:0] cosim_alu;
    wire [63:0] cosim_mem_addr;
    wire [ 3:0] cosim_mem_we;
    wire [63:0] cosim_mem_wdata;
    wire [63:0] cosim_mem_rdata;
    wire [ 3:0] cosim_rd_we;
    wire [ 7:0] cosim_rd_id;
    wire [63:0] cosim_rd_data;
    wire [ 3:0] cosim_br_taken;
    wire [63:0] cosim_npc;
    wire [63:0] cosim_disp;
    wire [63:0] cosim_mtime;
    wire [63:0] cosim_mtimecmp;

    CSRStruct::CSRPack        cosim_csr_info;
    RegStruct::RegPack        cosim_regs;

    DDR_ift ddr_request ();
    DDRStruct::DDRDebugCorePack ddr_debug_core;
    Uart_ift uart_ift ();
    MMUStruct::MMUPack cosim_mmu_info;

    wire               ui_clk_sync_rst;

    PipelineCPU dut (
        .clk (clk_core),
        .rstn(~ui_clk_sync_rst),

        .ddr_request   (ddr_request.Master),
        .ddr_debug_core(ddr_debug_core),
        .uart_ift      (uart_ift.Master),

        .cosim_valid    (cosim_valid),
        .cosim_pc       (cosim_pc),
        .cosim_inst     (cosim_inst),
        .cosim_rs1_id   (cosim_rs1_id),
        .cosim_rs1_data (cosim_rs1_data),
        .cosim_rs2_id   (cosim_rs2_id),
        .cosim_rs2_data (cosim_rs2_data),
        .cosim_alu      (cosim_alu),
        .cosim_mem_addr (cosim_mem_addr),
        .cosim_mem_we   (cosim_mem_we),
        .cosim_mem_wdata(cosim_mem_wdata),
        .cosim_mem_rdata(cosim_mem_rdata),
        .cosim_rd_we    (cosim_rd_we),
        .cosim_rd_id    (cosim_rd_id),
        .cosim_rd_data  (cosim_rd_data),
        .cosim_br_taken (cosim_br_taken),
        .cosim_npc      (cosim_npc),
        .cosim_csr_info (cosim_csr_info),
        .cosim_regs     (cosim_regs),
        .cosim_disp     (cosim_disp),
        .cosim_mtime    (cosim_mtime),
        .cosim_mtimecmp (cosim_mtimecmp),
        .cosim_mmu_info (cosim_mmu_info),

        .cosim_mmio_store(cosim_mmio_store),
        .cosim_mmio_len  (cosim_mmio_len),
        .cosim_mmio_val  (cosim_mmio_val),
        .cosim_mmio_addr (cosim_mmio_addr),
        .cosim_interrupt (cosim_interrupt),
        .cosim_cause     (cosim_cause)
    );

    IO io (
        .clk            (clk),
        .rstn           (rstn),
        .clk_core       (clk_core),
        .switch         (switch),
        .btn            (btn),
        .cs             (cs),
        .an             (an),
        .vga_r          (vga_r),
        .vga_g          (vga_g),
        .vga_b          (vga_b),
        .vga_hs         (vga_hs),
        .vga_vs         (vga_vs),
        .led            (led),
        .ui_clk_sync_rst(ui_clk_sync_rst),

        .ddr_request   (ddr_request.Slave),
        .uart_ift      (uart_ift.Slave),
        .ddr_debug_core(ddr_debug_core),

        .ddr2_cs_n (ddr2_cs_n),
        .ddr2_addr (ddr2_addr),
        .ddr2_ba   (ddr2_ba),
        .ddr2_we_n (ddr2_we_n),
        .ddr2_ras_n(ddr2_ras_n),
        .ddr2_cas_n(ddr2_cas_n),
        .ddr2_ck_n (ddr2_ck_n),
        .ddr2_ck_p (ddr2_ck_p),
        .ddr2_cke  (ddr2_cke),
        .ddr2_dq   (ddr2_dq),
        .ddr2_dqs_n(ddr2_dqs_n),
        .ddr2_dqs_p(ddr2_dqs_p),
        .ddr2_dm   (ddr2_dm),
        .ddr2_odt  (ddr2_odt),

        .cosim_valid    (cosim_valid),
        .cosim_pc       (cosim_pc),
        .cosim_inst     ({32'b0, cosim_inst}),
        .cosim_rs1_id   ({56'b0, cosim_rs1_id}),
        .cosim_rs1      (cosim_rs1_data),
        .cosim_rs2_id   ({56'b0, cosim_rs2_id}),
        .cosim_rs2      (cosim_rs2_data),
        .cosim_alu      (cosim_alu),
        .cosim_mem_addr (cosim_mem_addr),
        .cosim_mem_we   ({60'b0, cosim_mem_we}),
        .cosim_mem_wdata(cosim_mem_wdata),
        .cosim_mem_rdata(cosim_mem_rdata),
        .cosim_rd_id    ({56'b0, cosim_rd_id}),
        .cosim_rd_we    ({60'b0, cosim_rd_we}),
        .cosim_rd       (cosim_rd_data),
        .cosim_br_taken ({60'b0, cosim_br_taken}),
        .cosim_npc      (cosim_npc),

        .cosim_csr_info(cosim_csr_info),
        .cosim_regs    (cosim_regs),

        .cosim_disp    (cosim_disp),
        .cosim_mtime   (cosim_mtime),
        .cosim_mtimecmp(cosim_mtimecmp),
        .cosim_mmu_info(cosim_mmu_info)
    );

endmodule

